﻿
#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SQLite;
using System.Data;
using System.Runtime.InteropServices;
using FasterWPF;
using WPFContrib;
using WPFContribDataAccess;
using Microsoft.Research.DynamicDataDisplay;
using System.Collections.Specialized;
using System.Collections;
using Microsoft.Research.DynamicDataDisplay.Common;
using Microsoft.Research.DynamicDataDisplay.DataSources;
using WPFContribPresenters;
using System.Reactive;
using System.Reactive.Linq;
#endregion

namespace WPFContribDemo
{
    public partial class MainWindow : CPSBaseWindow
    {
        Canvas cnvs = null;
        Grid mainGrid = null;

        public MainWindow()
        {
            base.StartInitializeComponent(Brushes.Silver, new Thickness(2));

            string userCtlGuid = Guid.NewGuid().ToString();
            ChartUserControl usc = new ChartUserControl();
            usc.UserControlGuid = userCtlGuid;
            usc.LoadUserControl();

            #region Data Access

            DataAccessFactory daf = new DataAccessFactory(@"Data Source=test;Version=3;SetDefaults=true", SQLParms.DataAccessType.SQLite);
            ISimpleDataAccess sqliteDataAccess = daf.DataAccess;

            string fullpath = App.ResourceAssembly.Location.Replace(@"WPFContribDemo.exe", "");
            DataAccessFactory excel_daf = new DataAccessFactory(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fullpath + @"MyExcel.xls;Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';",
                SQLParms.DataAccessType.OleDB);

            ISimpleDataAccess excel_sqliteDataAccess = excel_daf.DataAccess;
            excel_sqliteDataAccess.SQLParms.ColumnNames = new List<string>() { "ID", "Name" };
            string countOfEmployees = "0";
            if (excel_sqliteDataAccess != null)
            {
                countOfEmployees = excel_sqliteDataAccess.Count("MyExcel.[Employees$]").ToString();
            }

            //Add();
            long totalRecords = 0;
            if (sqliteDataAccess != null)
            {
                totalRecords = sqliteDataAccess.Count("SECDATA");
            }

            ListBox lbx = new ListBox();
            lbx.Initialize(497.00D, 300.00D, ContainerType.HorizontalPanel);
            //lbx.UseHorizontalListBox();
            lbx.Background = Brushes.AntiqueWhite;
            lbx.BeginSettings().SetSelectedContentControlColor(Colors.Green)
                .SetBackgroundColorOnItemsControl(Brushes.Black)
                .SetAlternatingRows(Brushes.Yellow, Brushes.Khaki)
                .SetScrollViewerCornerRectangleColor(Brushes.Green)
                .SubscribeSelectionChangedOnParent((o,e)=>{ MessageBox.Show("hello world!");})
                .EndSettings();
            ContentControl cc = new ContentControl();
            cc.Initialize(ContainerType.Canvas);


            sqliteDataAccess.LoadData("SECDATA", "0", 198.ToString(), new System.Action<DataRow>(dr =>
            {
                lbx.BeginComposite().AddText(0, 0, "ID: " + dr[0].ToString())
                    .AddText(0, 1, "  " + dr[4].ToString())
                    .EndComposite<ListBox, ListBoxArgs>(null);
            }));

            excel_sqliteDataAccess.LoadData("MyExcel.[Employees$]", "0", 2.ToString(), new System.Action<DataRow>(dr =>
            {
                lbx.BeginComposite().AddText(0, 0, "ID: " + dr[0].ToString())
                    .AddText(0, 1, "  " + dr[1].ToString())
                    .EndComposite<ListBox, ListBoxArgs>(null);
            }));

            lbx.SortByText(0, 0, CommonExt.SortOrder.Desc, CommonExt.SortControlType.TextBlock);
            #endregion

            #region Setup Foundation

            cnvs = base.Canvas;
            mainGrid = new Grid();

            Application.Current.Properties["Canvas"] = cnvs;

            string cnvsguidAdorner = base.AdornerDecoratorGuid;

            base.AddMainParentToWindow(adornerDecorator =>
            {
                adornerDecorator.BeginComposite<AdornerDecorator>()
                               .AddExisting<Grid, AdornerDecorator>(0, 0, mainGrid)
                               .EndComposite<AdornerDecorator, AdornerDecoratorArgs>(null);
            });

            //4. Main Grid
            mainGrid.Initialize(500D, 500D, 23D, ContainerType.ContentControlPanel, 4, 3, 1.0, GridUnitType.Star, 1.0, GridUnitType.Star, 100D, GridUnitType.Pixel);
            //  mainGrid.SetCompositeDockPanelLastChildFill(true);
            //  mainGrid.CompositeDockPanelLastChildFill<Grid>(true);

            mainGrid.ShowGridLines = false;

            mainGrid.Visibility = Visibility.Hidden;

            Application.Current.Properties["MainGrid"] = mainGrid;

            #endregion

            #region Flat image buttons

            Grid arrowImageButton3 = null;
            Grid arrowImageButton4 = null;
            Grid arrowImageButton5 = null;
            Grid arrowImageButton7 = null;

            #endregion

            Brush darkBlue = BrushExt.CreateSolidColorBrushFromString("Green");

            mainGrid.BeginSettings<Grid>()
                .SetItemBorderSettings<Grid>(double.NaN, double.NaN, Brushes.Silver, new Thickness(2))
                .SetFontOnLabel(0, 0, "Segoe UI", 20, FontWeights.Bold, FontStyles.Normal)
                .Set<TextBox, Grid>("HorizontalAlignment", System.Windows.HorizontalAlignment.Stretch)
                .Set<DatePicker, Grid>("HorizontalAlignment", System.Windows.HorizontalAlignment.Stretch)
                .Set<Rectangle, Grid>("Height", 50D)
                .Set<Label, Grid>("Padding", new Thickness(5, 25, 5, 5))
                .SetHorizontalAlignmentForLabel(0, 0, System.Windows.HorizontalAlignment.Center)
                .EndSettings<Grid>();

            //Reactive Framework (Rx) example - leveraging an Observable
            Border labelComposite = null;
            //mainGrid.SubscribeMouseSingleClickOnBorder<Grid>(new Action<Object, MouseButtonEventArgs>((o, me) => { labelComposite.Background = (Brushes.Black); }));

            labelComposite = mainGrid.BeginComposite()
                   .AddLabel(0, 0, "0", darkBlue, Brushes.White)
                   .SubscribeEventOnChild<Label, Grid, MouseButtonEventArgs>(0, 0, "PreviewMouseLeftButtonDown", ((o, e) => { (o as Label).Content = (Int32.Parse((o as Label).Content.ToString())) + 1; }), (connectableObservable, actionDelegate) => { connectableObservable.Skip(2).Subscribe(actionDelegate); })
                   .SubscribeDependencyEventOnChild<Label, Grid>(0, 0, "IsEnabledChanged", (o, ve) => { System.Windows.MessageBox.Show(ve.NewValue.ToString() + "FRP"); })
                   .EndComposite(new GridArgs(0, 1));

            labelComposite.ToolTip = "hi!";

            #region Commented Out Code - Playing Around With Observables

            //labelComposite.SubscribeDependencyEventOnBorder<Grid>(labelComposite.GetKey(), "IsMouseDirectlyOverChanged", evp => { labelComposite.Background = ((bool)evp.EventArgs.NewValue) ? (Brushes.Beige) : (Brushes.LightGreen); });

            //var mouseSingleClick = labelComposite.AddExtraObservableFromBorder<MouseButtonEventArgs, Label, Grid>(0, 0, "PreviewMouseLeftButtonDown");

            //var anotherDisposable = mouseSingleClick.Take(2).Subscribe(eventPattern =>
            //{
            //    System.Windows.MessageBox.Show("On Next! " + eventPattern.EventArgs.ButtonState.ToString());
            //});
            //((mainGrid.GetDisposablesDictionary().ElementAt(0).Value as FasterWPF.CommonExt.ObservableDisposer).ObservableObject as IObservable<EventPattern<MouseButtonEventArgs>>).Take(2).Subscribe(eventPattern =>
            //{
            // System.Windows.MessageBox.Show("Clicked!");

            //});
            ////anotherDisposable.Dispose();

            //labelComposite.GetObservableFromBorder<MouseButtonEventArgs, Label, Grid>(0, 0, "PreviewMouseLeftButtonDown").Take(2).Subscribe(eventPattern =>
            //{
            //    System.Windows.MessageBox.Show("Change label enabled property! " + eventPattern.EventArgs.ButtonState.ToString());

            //    //Toggle Enabled Property
            //    labelComposite.GetChildFromComposite<Label, Grid>(0, 0).IsEnabled = !labelComposite.GetChildFromComposite<Label, Grid>(0, 0).IsEnabled;
            //});

            //labelComposite.GetObservableFromBorder<ValueChangedEventArgs, Label, Grid>(0, 0, "IsEnabledChanged").Take(2).Subscribe(eventPattern =>
            //{
            //    System.Windows.MessageBox.Show("Dependency property observable! " + eventPattern.EventArgs.OldValue.ToString());
            //});

            //labelComposite.GetChildFromComposite<Label, Grid>(0, 0).IsEnabled = true;

            //dispose Original Event that says "hello!"
            //(iDispDictry.Values.First() as FasterWPF.CommonExt.EventDisposer).Dispose();

            #endregion

            mainGrid.BeginComposite()
                   .AddExisting<ListBox, Grid>(1, 1, lbx)
                   .EndComposite(new GridArgs(2, 1));

            #region SQUARES NAVIGATOR

            SquaresNavigator squaresNav = new SquaresNavigator();

            Action<object, System.Windows.Input.MouseButtonEventArgs, string, string, string> loadDataAction = (o, me, counter, increment, name) =>
            {
                string counterCopy = counter;

                //Selectors.DisposeEventsOnAllParents(lbx); 
                lbx.RemoveAll();
                sqliteDataAccess.LoadData("SECDATA", counterCopy, increment, dr =>
                {
                    lbx.BeginComposite().AddText(0, 0, "ID: " + dr[0].ToString())
                        .AddText(0, 1, "  " + dr[4].ToString())
                        .EndComposite<ListBox, ListBoxArgs>(null);
                });

                Label lbl = squaresNav.NameDisplayLabel;
                lbl.Content = "ID: " + counter + " " + name;
            };

            Action<object, ValueChangedEventArgs, string, string, string> onMouseOverAction = (o, me, counter, increment, name) =>
            {
                Border source2 = null;
                if (o is Border)
                {
                    source2 = o as Border;
                }

                if (source2 != null && source2.IsMouseDirectlyOver)
                {
                    Label lbl = squaresNav.NameDisplayLabel;
                    lbl.Content = "ID: " + counter + " " + name;
                }
            };

            long totalRecordsSECDATA = 0;
            totalRecordsSECDATA = sqliteDataAccess.Count("SECDATA");
            List<string> cachedFundNames = new List<string>();
            StringBuilder proportionalListOfIDs = SquaresNavigator.GetProportionalListOfIDs(totalRecordsSECDATA);

            sqliteDataAccess.LoadSubsetOfNames("Series_Name", "SECDATA", proportionalListOfIDs.ToString(), dataRow => { cachedFundNames.Add(dataRow[0].ToString()); });

            squaresNav.AddSquares(totalRecordsSECDATA, cachedFundNames, "Series_Name", "SECDATA", Brushes.White, Brushes.Silver, loadDataAction, onMouseOverAction);

            squaresNav.InnerStackPanel.Background = Brushes.AntiqueWhite;
            squaresNav.TitleLabel.Background = Brushes.AntiqueWhite;

            mainGrid.BeginComposite()
                  .AddExisting<StackPanel, Grid>(1, 1, squaresNav.InnerStackPanel)
                  .EndComposite(new GridArgs(2, 2));

            #endregion

            #region Paging Control - instantiating and storing Actions

            PageSamplePresenter pgsp = new PageSamplePresenter();

            StackPanel pagingControlStackPanel = pgsp.BuildPagingControl(totalRecords, sqliteDataAccess);

            pgsp.PerformInitialLoadOfData(pagingControlStackPanel, sqliteDataAccess);
            //pgsp.PagingControl.NextButton.Background = Brushes.Orange;

            ActionAggregator.CreateActionStore<PageSamplePresenter>();
            ActionAggregator.Put<PageSamplePresenter>("MainWindow_PageNext", pgsp.ActionPageNext(pagingControlStackPanel));
            ActionAggregator.Put<PageSamplePresenter>("MainWindow_PagePrevious", pgsp.ActionPagePrev(pagingControlStackPanel));

            #endregion

            #region Commented Out Code
            //foreach (DataRow dr in sql_parms.DT.Rows)
            //{
            //    lbx.BeginComposite().AddText(0, 0, dr[0].ToString()).EndComposite<ListBox, ListBoxArgs>(null);
            //}
            #endregion

            #region FLAT IMAGE BUTTONS

            //Geometry examples sourced from Syncfusion Metro Studio 2 - copyright free icons
            string iconPath3 = @"M5.2010002,14.812L5.2010002,43.573997 56.098,43.573997 56.098,14.812z M29.868601,3.8869994C28.026201,3.8869996 26.534,5.3791947 26.534,7.2190399 26.534,9.0588851 28.026201,10.553 29.868601,10.553 31.7085,10.553 33.202,9.0588851 33.202,7.2190399 33.202,5.3791947 31.7085,3.8869996 29.868601,3.8869994z M19.200649,3.8869994C17.359457,3.8869996 15.867001,5.3791947 15.867001,7.2190399 15.867001,9.0588851 17.359457,10.553 19.200649,10.553 21.042044,10.553 22.536999,9.0588851 22.536999,7.2190399 22.536999,5.3791947 21.042044,3.8869996 19.200649,3.8869994z M8.5339746,3.8869994C6.6931,3.8869996 5.2010002,5.3791947 5.2010002,7.2190399 5.2010002,9.0588851 6.6931,10.553 8.5339746,10.553 10.37495,10.553 11.867,9.0588851 11.867,7.2190399 11.867,5.3791947 10.37495,3.8869996 8.5339746,3.8869994z M0,0L63.999001,0 63.999001,48.792999 0,48.792999z";
            arrowImageButton3 = FlatButtonHelpers.CreateFlatGeometryButton(iconPath3, FlatButtonHelpers.GeometryButtonSize.Large, BrushExt.CreateSolidColorBrushFromString("Green"), BrushExt.CreateSolidColorBrushFromString("#FFFFFFFF"), Brushes.Black, Brushes.WhiteSmoke, Brushes.Gray, new Thickness(1), new Thickness(1), "Toggle Label",
                    (sender, e) => { }, (o, ev) => { 
                        labelComposite.Visibility = (labelComposite.Visibility == Visibility.Visible) ? Visibility.Collapsed : Visibility.Visible;
                        pgsp.PagingControl.MainDataGrid.Refresh();
                    });

            string iconPath4 = @"M299.134,162.984L334.087,194.984 299.134,226.984 299.134,162.984z";
            arrowImageButton4 = FlatButtonHelpers.CreateFlatGeometryButton(iconPath4, FlatButtonHelpers.GeometryButtonSize.Small, BrushExt.CreateSolidColorBrushFromString("Green"), BrushExt.CreateSolidColorBrushFromString("#FFFFFFFF"), Brushes.Black, Brushes.WhiteSmoke, Brushes.Gray, new Thickness(1), new Thickness(1), "Page Next",
                   (sender, e) => { }, (o, ev) => { ActionAggregator.Fire<PageSamplePresenter>("MainWindow_PageNext"); });

            string iconPath5 = @"M582.309,226.984L547.355,194.984 582.309,162.984 582.309,226.984z";
            arrowImageButton5 = FlatButtonHelpers.CreateFlatGeometryButton(iconPath5, FlatButtonHelpers.GeometryButtonSize.Small, BrushExt.CreateSolidColorBrushFromString("Green"), BrushExt.CreateSolidColorBrushFromString("#FFFFFFFF"), Brushes.Black, Brushes.WhiteSmoke, Brushes.Gray, new Thickness(1), new Thickness(1), "Page Previous",
                  (sender, e) => { }, (o, ev) => { ActionAggregator.Fire<PageSamplePresenter>("MainWindow_PagePrevious"); });

            string iconPath7 = @"M19.833,0L32.5,0 32.5,19.833999 52.334,19.833999 52.334,32.500999 32.5,32.500999 32.5,52.333 19.833,52.333 19.833,32.500999 0,32.500999 0,19.833999 19.833,19.833999z";
            arrowImageButton7 = FlatButtonHelpers.CreateFlatGeometryButton(iconPath7, FlatButtonHelpers.GeometryButtonSize.Large, BrushExt.CreateSolidColorBrushFromString("Green"), BrushExt.CreateSolidColorBrushFromString("#FFFFFFFF"), Brushes.Black, Brushes.WhiteSmoke, Brushes.Gray, new Thickness(1), new Thickness(1), "Add UserControl to Region",
                 (sender, e) => { }, (o, ev) => { ActionAggregator.Fire<ChartUserControl>("RegionOneAdd"); });

            #endregion

            #region ADD FLAT IMAGE BUTTONS
            StackPanel flatRibbon = new StackPanel();
            flatRibbon.Initialize(192, 48, ContainerType.ContentControlPanel, Orientation.Horizontal);

            flatRibbon.BeginComposite()
                .AddExisting(0, 0, arrowImageButton3)
                .EndComposite(new StackPanelArgs(Orientation.Horizontal));

            flatRibbon.BeginComposite()
                .AddExisting(0, 0, arrowImageButton5)
                .EndComposite(new StackPanelArgs(Orientation.Horizontal));

            flatRibbon.BeginComposite()
                .AddExisting(0, 0, arrowImageButton4)
                .EndComposite(new StackPanelArgs(Orientation.Horizontal));

            Border imgButtonComposite = mainGrid.BeginComposite()
                   .AddExisting(0, 0, flatRibbon)
                   .EndComposite(new GridArgs(0, 0));

            Border imgButtonComposite7 = mainGrid.BeginComposite()
                   .AddExisting(0, 0, arrowImageButton7)
                   .EndComposite(new GridArgs(0, 2));
            #endregion

            #region Paging Control - adding to Main Grid

            Border pagingControlComposite = mainGrid.BeginComposite()
                .AddExisting<StackPanel, Grid>(0, 0, pagingControlStackPanel)
                .EndComposite(new GridArgs(1, 0));

            Grid.SetRowSpan(pagingControlComposite, 3);

            #endregion

            #region Add User Control Region and User Control

            UserControlRegion regionOne = new UserControlRegion(Brushes.LightGreen);
            string userControlRegionkey = regionOne.AddUserControl(usc);

            usc.BuildAndStoreRemoveAction(usc, regionOne);
            usc.BuildAndStoreAddAction(usc, regionOne);

            StackPanel stkcpanel2 = Factory.InitStackPanel(ContainerType.VerticalPanel, Orientation.Horizontal, Brushes.Transparent, 1, 1);
            stkcpanel2.BeginComposite<StackPanel>()
              .AddLabel<StackPanel>(0, 1, "Below is a re-usable UserControl in a UserControlRegion (Border).", Brushes.Transparent)
              .AddExisting<Border, StackPanel>(0, 2, regionOne) //Add UserControl via a Border "region"
              .EndComposite<StackPanel, StackPanelArgs>(null);

            Border plotterComposite = mainGrid.BeginComposite()
                .AddExisting<StackPanel, Grid>(0, 0, stkcpanel2)
                .EndComposite(new GridArgs(1, 2));

            //Create Tab Item
            string tabCtlGuid1 = Guid.NewGuid().ToString();
            TabItem tabItm1 = new TabItem() { Name = "TabItem1" };
            tabItm1.Initialize(100D, 100D, ContainerType.Grid);
            tabItm1.SetCompositeGridDimensions<TabItem>(100D, 100D, 1, 1, double.NaN, GridUnitType.Pixel, double.NaN, GridUnitType.Pixel);
            tabItm1.BeginSettings<TabItem>().SetItemBorderSettings<TabItem>(double.NaN, double.NaN, Brushes.Black, new Thickness(1)).EndSettings<TabItem>();

            Label one = new Label();
            one.Content = "One";
            tabItm1.BeginComposite().AddExisting<Label, TabItem>(0, 0, one)
            .EndComposite<TabItem, TabItemArgs>(null);

            //Create Tab Item
            string tabCtlGuid2 = Guid.NewGuid().ToString();
            TabItem tabItm2 = new TabItem() { Name = "TabItem2" };
            tabItm2.Initialize(100D, 100D, ContainerType.Grid);
            tabItm2.SetCompositeGridDimensions<TabItem>(100D, 100D, 1, 1, double.NaN, GridUnitType.Pixel, double.NaN, GridUnitType.Pixel);
            tabItm2.BeginSettings<TabItem>().SetItemBorderSettings<TabItem>(double.NaN, double.NaN, Brushes.Black, new Thickness(1)).EndSettings<TabItem>();

            Label two = new Label();
            two.Content = "Two";
            tabItm2.BeginComposite().AddExisting<Label, TabItem>(0, 0, two)
            .EndComposite<TabItem, TabItemArgs>(null);

            //Add Tab Items to Tab Control           
            TabControl tabCtl = new TabControl();
            tabCtl.Background = Brushes.White;

            tabCtl.Initialize(200D, 200D, ContainerType.HorizontalPanel);

            tabCtl.BeginComposite<TabControl>(tabCtlGuid1)
                .AddCustomTabItem<TabControl>(0, 0, FasterWPF.Factory.NewTabHeader(tabCtl, Brushes.Black, Brushes.LightGray, Brushes.Black, Brushes.LightGreen, "One", true, (o, e) =>
                {
                    //This is the Close Tab Action - action that fires upon clicking the X on the Tab
                    Application.Current.Properties["TabToBeRemoved"] = "Custom" + tabItm1.Name;
                    tabCtl.RemoveByKey(tabCtlGuid1);
                    Application.Current.Properties["TabToBeRemoved"] = null;

                }), tabItm1)
                .EndComposite<TabControl, TabControlArgs>(null);

            tabCtl.BeginComposite<TabControl>(tabCtlGuid2)
               .AddCustomTabItem<TabControl>(0, 0, FasterWPF.Factory.NewTabHeader(tabCtl, Brushes.Black, Brushes.LightGray, Brushes.Black, Brushes.LightGreen, "Two", true, (o, e) =>
               {
                   //This is the Close Tab Action - action that fires upon clicking the X on the Tab

                   //Application.Current.Properties["TabToBeRemoved"] = "Custom" + tabItm2.Name;
                   tabCtl.RemoveByKey(tabCtlGuid2);
                   Application.Current.Properties["TabToBeRemoved"] = null;
               }), tabItm2)
               .EndComposite<TabControl, TabControlArgs>(null);

            Border lblComposite = mainGrid.BeginComposite()
            .AddExisting<TabControl, Grid>(0, 0, tabCtl)
            .EndComposite(new GridArgs(1, 1));

            //Select Second Tab
            tabCtl.SelectedIndex = (1);
            #endregion

            #region Other

            ContentControlPanel dockPanelWithImgButton = mainGrid.GetContainerFromComposite<ContentControlPanel, Grid>(imgButtonComposite);

            dockPanelWithImgButton.Background = Brushes.LightGray;

            base.EndInitializeComponent();

            mainGrid.Visibility = Visibility.Visible;

            #endregion
        }

        protected override void ResizeCorrectly()
        {
            Double myWindowHeight = base.WindowHeight;
            Double myWindowWidth = base.WindowWidth - 10;

            if (myWindowWidth > 0)
            {
                if (((FrameworkElement)Application.Current.Properties["Canvas"]) != null)
                {
                    ((FrameworkElement)Application.Current.Properties["Canvas"]).Height = myWindowHeight;
                    ((FrameworkElement)Application.Current.Properties["Canvas"]).Width = myWindowWidth;
                }

                if (((FrameworkElement)Application.Current.Properties["MainGrid"]) != null)
                {
                    ((FrameworkElement)Application.Current.Properties["MainGrid"]).Height = myWindowHeight;
                    ((FrameworkElement)Application.Current.Properties["MainGrid"]).Width = myWindowWidth;
                }
            }
        }

    }//end of class
}//end of namespace


